package com.yanqu.road.server.manger.activity.goldautumn;

import com.yanqu.road.dao.impl.activity.goldautumn.GoldAutumnConfigDaoImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.goldautumn.GoldAutumnCell;
import com.yanqu.road.entity.activity.goldautumn.GoldAutumnConfig;
import com.yanqu.road.entity.activity.goldautumn.GoldAutumnUserData;
import com.yanqu.road.entity.activity.goldautumn.config.GoldAutumnLatticeInfo;
import com.yanqu.road.entity.activity.goldautumn.config.GoldAutumnLevelInfo;
import com.yanqu.road.entity.activity.goldautumn.config.GoldAutumnScreedInfo;
import com.yanqu.road.entity.enums.eActivityConfigType;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.goldautumn.GoldAutumnJumpPlanResult;
import com.yanqu.road.server.gameplayer.module.activity.goldautumn.GoldAutumnModule;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.*;

public class GoldAutumnMgr extends TempMgr {

    static GoldAutumnConfig config;

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }


    public static void reloadActivityData() {
        getLogger().info("reload GoldAutumn Activity start");

        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.GoldAutumn.getValue());
        if (openActivityInfoList.isEmpty()) {
            getLogger().info("no GoldAutumn Activity in show time");
            config = null;

        } else {

            ActivityInfo activityInfo = openActivityInfoList.get(0);
            GoldAutumnConfig tempCardsConfig = new GoldAutumnConfig(activityInfo);
            int tmpActivityId = activityInfo.getActivityId();

            GoldAutumnConfigDaoImpl dao = new GoldAutumnConfigDaoImpl();
            tempCardsConfig.setBuffInfoList(dao.getGoldAutumnBuffInfoList(activityInfo.getActivityId()));
            tempCardsConfig.setLatticeInfoList(dao.getGoldAutumnLatticeInfoList(activityInfo.getActivityId()));
            tempCardsConfig.setLevelInfoList(dao.getGoldAutumnLevelInfoList(activityInfo.getActivityId()));
            tempCardsConfig.setScreedInfoList(dao.getGoldAutumnScreedInfoList(activityInfo.getActivityId()));

            //初始化配置
            Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(tmpActivityId);
            if(activityConfigMap != null){
                if(activityConfigMap.containsKey(eActivityConfigType.MID_AUTUMN_SCORE_ITEM_ID.getName())) {
                    tempCardsConfig.setSCORE_ITEM_ID(activityConfigMap.get(eActivityConfigType.MID_AUTUMN_SCORE_ITEM_ID.getName()).getIntValue());
                }else if(activityConfigMap.containsKey(eActivityConfigType.EXCHANGE_SCORE_ITEM_ID.getName())){
                    //历史问题，兼容线上
                    tempCardsConfig.setSCORE_ITEM_ID(activityConfigMap.get(eActivityConfigType.EXCHANGE_SCORE_ITEM_ID.getName()).getIntValue());
                }
                tempCardsConfig.setENERGY_ITEM_ID(activityConfigMap.get(eActivityConfigType.MID_AUTUMN_ENERGY_ITEM_ID.getName()).getIntValue());
//                tempCardsConfig.setLATTICE_CIRCULATE(activityConfigMap.get(eActivityConfigType.MID_AUTUMN_LATTICE_CIRCULATE.getName()).getIntValue());
                tempCardsConfig.setRED_LATTICE(activityConfigMap.get(eActivityConfigType.MID_AUTUMN_RED_LATTICE.getName()).getValue());
//                tempCardsConfig.setEND_SCREED(activityConfigMap.get(eActivityConfigType.MID_AUTUMN_END_SCREED.getName()).getValue());
                tempCardsConfig.setSCORE_ITEM_NUMBER(activityConfigMap.get(eActivityConfigType.MID_AUTUMN_ACHIEVE_SCORE_ITEM_NUMBER.getName()).getIntValue());

                tempCardsConfig.setAUTUMN_AUTO_OPEN(activityConfigMap.get(eActivityConfigType.MID_AUTUMN_AUTO_OPEN.getName()).getIntValue());
            }
            tempCardsConfig.initRedConfig();

            config = tempCardsConfig;
        }

        for (GamePlayer player : GamePlayerMgr.getAllOnlinePlayer()) {
            player.getModule(GoldAutumnModule.class).activityReload();
        }

        getLogger().info("reload GoldAutumn Activity finish");
    }

    public static List<List<Integer>> getCombination(List<Integer> targetList, int num){
        if(targetList.size() < num){
            return new ArrayList<>();
        }
        List<List<Integer>> resultLit = new ArrayList<>();
        recursion(targetList, 0, num, new ArrayList<>(), resultLit);
        return resultLit;
    }

    //万能百度
    public static void recursion(List<Integer> targetList, int cur, int max, List<Integer> stack, List<List<Integer>> resultList){
        if(cur == max){
            resultList.add(new ArrayList<>(stack));
            return;
        }
        for (Integer val : targetList) {
            if(!stack.contains(val)){
                stack.add(val);
                recursion(targetList, cur + 1, max, stack, resultList);
                if(stack.size() > 0) {
                    stack.remove(stack.size() - 1);
                }
            }
        }
    }

    /**
     * 循环生成最近的格子
     * @param lastCellList 已经提前生成的格子
     * @param curCellId 当前所在格子
     * @param maxCellId 最大格子数
     * @param config 配置
     */
    public static List<GoldAutumnCell> initNextCell(List<GoldAutumnCell> lastCellList, int curCellId, int maxCellId, GoldAutumnConfig config){
        //往后预览30格
        int viewNum = 3;
        List<GoldAutumnCell> cellList = new ArrayList<>();
        if(curCellId + viewNum * 10 > maxCellId){
            Random random = new Random();
            int max = maxCellId;
            for (int i = 0; i < viewNum; i++) {
                //判断是否已经生成过
                List<GoldAutumnCell> cacheList = getCache(max, 10, lastCellList);
                if(cacheList.size() == 10){
                    cellList.addAll(cacheList);
                    max += cacheList.size();
                    continue;
                }else if(cacheList.size() != 0){
                    getLogger().info("生成格子错误， {}，{}，{}", curCellId, max, cacheList.size());
                }
                GoldAutumnScreedInfo screedInfo = config.randomGoldAutumnScreedInfo(max, random);
                List<Integer> addList = getRandomColor(random, screedInfo);
                if (addList == null) {
                    continue;
                }
                cellList.addAll(initCellParam(max, addList, config));
                max += addList.size();
            }
        }
        return cellList;
    }

    private static List<GoldAutumnCell> getCache(int max, int count, List<GoldAutumnCell> lastCellList) {
        List<GoldAutumnCell> result = new ArrayList<>();
        Iterator<GoldAutumnCell> iterator = lastCellList.iterator();
        while (iterator.hasNext()){
            GoldAutumnCell cell = iterator.next();
            if(cell.getId() > max && cell.getId() <= max + count){
                result.add(cell);
                iterator.remove();
            }
        }
        return result;
    }

    public static List<Integer> getRandomColor(Random random, GoldAutumnScreedInfo screedInfo) {
        List<String> tempList = StringUtils.stringToStringList(screedInfo.getParam(), "\\|");
        List<Integer> poolList = new ArrayList<>();
        List<Integer> addList = new ArrayList<>();
        for (String tempParam : tempList) {
            List<Integer> paramList = StringUtils.stringToIntegerList(tempParam, ",");
            for (int k = 0; k < paramList.get(1); k++) {
                poolList.add(paramList.get(0));
            }
        }
        if(poolList.size() != 10){
            getLogger().info("模板格子配置错误，{}, {}", screedInfo.getId(), screedInfo.getParam());
            return null;
        }
        while (poolList.size() > 0){
            addList.add(poolList.remove(random.nextInt(poolList.size())));
        }
        return addList;
    }

    /**
     * 初始格子参赛
     * @param start 开始
     * @param addList 格子颜色列表
     * @param config 配置
     * @return
     */
    public static List<GoldAutumnCell> initCellParam(int start, List<Integer> addList, GoldAutumnConfig config) {
        List<GoldAutumnCell> list = new ArrayList<>();
        Random random = new Random();
        GoldAutumnLevelInfo levelInfo = getByCostNum(start, config);
        for (Integer type : addList) {
            GoldAutumnLatticeInfo latticeInfo = config.randomLattice(levelInfo.getId(), type);
            GoldAutumnCell cell = new GoldAutumnCell();
            cell.setId(++start);
            cell.setCid(latticeInfo.getId());
            cell.setCt(latticeInfo.getColorType());

            if(config.getRedRewardMap().containsKey(start)){
                //红色大奖
                cell.setCt(5);
                cell.setCid(0);
                cell.setR(config.getRedRewardMap().get(start));
            }else {
                //月兔事件
                if(latticeInfo.getType() == 3) {
                    cell.setEid(3);
                }
                if(!StringUtils.isNullOrEmpty(latticeInfo.getReward()) && !"0".equals(latticeInfo.getReward())){
                    if(latticeInfo.getType() == 1){
                        //月桂币
                        cell.setR(latticeInfo.getReward());
                    }else {
                        //随机普通道具奖励
                        Property property = new Property();
                        List<String> rewardConfigList = StringUtils.stringToStringList(latticeInfo.getReward(), "\\|");
                        for (String rewardConfig : rewardConfigList) {
                            List<String> rewardWightList = StringUtils.stringToStringList(rewardConfig, "#");
                            List<String> rewardList = new ArrayList<>();
                            List<Integer> weightList = new ArrayList<>();
                            for (String s : rewardWightList) {
                                List<String> paramList = StringUtils.stringToStringList(s, ",");
                                if(paramList.size() == 2) {
                                    rewardList.add(paramList.get(0));
                                    weightList.add(Integer.parseInt(paramList.get(1)));
                                }else {
                                    GoldAutumnMgr.getLogger().info("latticeInfo config error {},{},{}", latticeInfo.getColorType(), latticeInfo.getType(), latticeInfo.getReward());
                                }
                            }
                            int idx = RandomHelper.getRandomIndexByWeight(weightList, random);
                            property.addProperty(PropertyHelper.parseStringToProperty(rewardList.get(idx)));
                        }
                        cell.setR(PropertyHelper.parsePropertyToString(property));
                    }
                }
            }
            list.add(cell);
        }
        return list;
    }

    public static GoldAutumnJumpPlanResult getBestJump(GoldAutumnUserData userData, int startCellId, List<Integer> poolList){
        if(poolList.size() == 0){
            return null;
        }
        if(poolList.size() == 1){
            GoldAutumnJumpPlanResult result = new GoldAutumnJumpPlanResult();
            result.setStepList(poolList);
            result.getCellList().add(getGoldAutumnCellById(userData, startCellId + poolList.get(0)));
            return result;
        }
        //多次，穷尽
        List<List<Integer>> resultList = GoldAutumnMgr.getCombination(poolList, poolList.size());
        List<GoldAutumnJumpPlanResult> jumpResultList = new ArrayList<>();
        for (List<Integer> sampleList : resultList) {
            int cur = startCellId;
            GoldAutumnJumpPlanResult result = new GoldAutumnJumpPlanResult();
            result.setStepList(sampleList);
            for (Integer add : sampleList) {
                cur += add;
                result.getCellList().add(getGoldAutumnCellById(userData, cur));
            }
            jumpResultList.add(result);
        }

        //评分
        jumpResultList.sort((o1, o2) -> o2.calScore() - o1.calScore());
        return jumpResultList.get(0);
    }

    public static GoldAutumnLevelInfo getByCostNum(int cellNum, GoldAutumnConfig config) {
        GoldAutumnLevelInfo temp = config.getLevelInfoList().get(0);
        for (GoldAutumnLevelInfo levelInfo : config.getLevelInfoList()) {
            if(cellNum >= levelInfo.getUnlock()){
                temp = levelInfo;
            }
        }
        return temp;
    }

    public static GoldAutumnCell getGoldAutumnCellById(GoldAutumnUserData userData, int cellId){
        for (GoldAutumnCell cell : userData.getCellList()) {
            if(cell.getId() == cellId){
                return cell;
            }
        }
        return null;
    }

    public static List<GoldAutumnCell> getGoldAutumnCellById(GoldAutumnUserData userData, int cellId, int count){
        List<GoldAutumnCell> list = new ArrayList<>();
        for (GoldAutumnCell cell : userData.getCellList()) {
            if(cell.getId() >= cellId){
                list.add(cell);
                count--;
            }
            if(count == 0){
                break;
            }
        }
        return list;
    }

    public static void main(String[] args) {
        List<List<Integer>> resultLit = new ArrayList<>();
        List<Integer> targetList = new ArrayList<>();
        targetList.add(1);
        targetList.add(2);
        targetList.add(3);
        targetList.add(4);
        recursion(targetList, 0, 3, new ArrayList<>(), resultLit);

        for (List<Integer> list : resultLit) {
            System.out.println(list);
        }
    }

    public static ActivityInfo getActivityInfo() {
        if(config == null){
            return null;
        }
        return config.getActivityInfo();
    }

    public static GoldAutumnConfig getConfig() {
        return config;
    }
}